<?php
/**
 * Created by PhpStorm
 * Author Hui
 * Date 2024/5/12   23:37
 */
declare(strict_types=1);

namespace designpatterns\tool;

/**
 * Env管理类
 */
class Env
{
    /**
     * 环境变量数据
     * @var array
     */
    protected $data = [];

    /**
     * 应用根目录
     * @var string
     */
    protected $rootPath = '';

    /**
     * 数据转化映射
     * @var array
     */
    protected $convert = [
        'false' => false,
        'true' => true,
        'off' => false,
        'on' => true,
    ];

    public function __construct($rootPath = '')
    {
        $this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath();
        $this->data = $_ENV;
        //加载配置
        $this->loadEnv();
    }


    public function loadEnv(string $envName = '') : void
    {
        $file = $envName ? $this->rootPath . '.env.' . $envName : $this->rootPath . '.env';
        if(is_file($file)){
            $this->load($file);
        }
    }

    /**
     * 读取环境变量定义文件
     * @param string $file 环境定义文件
     * @return void
     */
    public function load(string $file) :void
    {
        $env = parse_ini_file($file,true,INI_SCANNER_NORMAL);
        $this->set($env);
    }


    /**
     * 获取环境变量值
     * @param string|null $name
     * @param $default
     * @return array|mixed|string|null
     */
    public function get(string $name = null,$default = null)
    {
        if(is_null($name)){
            return $this->data;
        }

        $name = strtoupper(str_replace('.','_',$name));
        if(isset($this->data[$name])){
            $result = $this->data[$name];

            if(is_string($result) && isset($this->convert[$result])){
                return $this->convert[$result];
            }

            return $result;
        }

        return $this->getEnv($name,$default);
    }

    public function getEnv(string $name = null,$default = null)
    {
        $result = getenv('PHP_'.$name);
        if(false === $result){
            return $default;
        }

        if(isset($this->convert[$result])){
            $result = $this->convert[$result];
        }

        if(!$this->data[$name]){
            $this->data[$name] = $result;
        }

        return $result;
    }


    /**
     * 设置环境变量值
     * @param string|array $env
     * @param $value
     * @return void
     */
    public function set($env,$value = null) :void
    {
        if(is_array($env)){
            $env = array_change_key_case($env,CASE_UPPER);

            foreach ($env as $key => $val){
                if(is_array($val)){
                    foreach ($val as $k => $v){
                        $this->data[$key.'_'.strtoupper($k)] = $v;
                    }
                }else{
                    $this->data[$key] = $val;
                }
            }
        }else{
            $name = strtoupper(str_replace('.','_',$env));
            $this->data[$name] = $value;
        }
    }

    /**
     * 检测环境变量是否存在
     * @param string $name
     * @return bool
     */
    public function has(string $name) : bool
    {
        return !is_null($this->get($name));
    }

    /**
     * 设置环境变量
     * @param string $name
     * @param $value
     * @return void
     */
    public function __set(string $name, $value) :void
    {
         $this->set($name,$value);
    }

    /**
     * 读取环境变量
     * @param string $name
     * @return array|mixed|string|null
     */
    public function __get(string $name)
    {
        return $this->get($name);
    }

    /**
     * 设置环境变量
     * @param string $name
     * @return bool
     */
    public function __isset(string $name): bool
    {
        return $this->has($name);
    }


    public function getDefaultRootPath()
    {
        return dirname(__DIR__).DIRECTORY_SEPARATOR;
    }

}